<template>
	<view class="canvas_box" :hidden="canvasFlag">
		<view @touchmove.stop.prevent="{}">
			<canvas class="canvas" canvas-id="myCanvas"></canvas>
		</view>
		<view class="button-wrapper">
			<button class="save_btn" @click="saveCanvasImage">保存图片</button>
			<button class="close_btn" @click="canvasCancelEvn">关闭</button>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				form :[],
				jsonData :{}
			}
		},
		props: {
			canvasFlag: {
				type: Boolean,
				default: true,
			},
			posterObj: Object
		},
		watch:{
			'posterObj.form_id'(value){
				if(value > 0){
					this.form = this.$getConfig('forms',this.posterObj.form_id,'data')
					this.form.forEach(v =>{
						if(v.type == 'tree'){
							this.searchJson(v)
						}
					})
				}
			}
		},
		methods: {
			async searchJson(config){
				if(this.posterObj.form[config.field]){
					let data = JSON.stringify(await this.$api('GET','json',{url:config.json}))
					let arr = []
					this.posterObj.form[config.field].forEach(v =>{
						let s = data.indexOf('{"id":'+v+',')
						let n = data.indexOf('"name":"',s)
						let e = data.indexOf('"',n+8)
						let d = data.substring(n+8,e)
						arr.push(d)
					})
					this.jsonData[config.field] = arr.join(';')
				}
			},
			// 海报
			// 画圆角矩形 ctx、x起点、y起点、w宽度、h高度、r圆角半径、fillColor填充颜色、strokeColor边框颜色
			roundRect(ctx, x, y, w, h, r, fillColor, strokeColor, btn) {
				// 开始绘制
				ctx.beginPath()
				// 绘制左上角圆弧 Math.PI = 180度
				// 圆心x起点、圆心y起点、半径、以3点钟方向顺时针旋转后确认的起始弧度、以3点钟方向顺时针旋转后确认的终止弧度
				ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5)
				// 绘制border-top
				// 移动起点位置 x终点、y终点
				ctx.moveTo(x + r, y)
				// 画一条线 x终点、y终点
				ctx.lineTo(x + w - r, y)
				// 绘制右上角圆弧
				ctx.arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2)
				// 绘制border-right
				ctx.lineTo(x + w, y + h - r)
				// 绘制右下角圆弧
				ctx.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5)
				// 绘制左下角圆弧
				ctx.arc(x + r, y + h - r, r, Math.PI * 0.5, Math.PI)
				// 绘制border-left
				ctx.lineTo(x, y + r)
				if (btn == 'btn') {
					const grd = ctx.createLinearGradient(0, 0, 200, 0) //渐变色
					grd.addColorStop(0, fillColor)
					grd.addColorStop(1, strokeColor)
					// 因为边缘描边存在锯齿，最好指定使用 transparent 填充
					ctx.setFillStyle(grd)
					// 对绘画区域填充
					ctx.fill()
				} else {
					if (fillColor) {
						// 因为边缘描边存在锯齿，最好指定使用 transparent 填充
						ctx.setFillStyle(fillColor)
						// 对绘画区域填充
						ctx.fill()
					}
					if (strokeColor) {
						// 因为边缘描边存在锯齿，最好指定使用 transparent 填充
						ctx.setStrokeStyle(strokeColor)
						// 画出当前路径的边框
						ctx.stroke()
					}
				}
				// 关闭一个路径
				ctx.closePath()
				// 剪切，剪切之后的绘画绘制剪切区域内进行，需要save与restore 这个很重要 不然没办法保存
				ctx.clip()
			},
			/**
			 * canvas绘图相关，把文字转化成只能行数，多余显示省略号
			 * ctx: 当前的canvas
			 * text: 文本
			 * contentWidth: 文本最大宽度
			 * lineNumber: 显示几行
			 */
			canvasMultiLineText(ctx, text, contentWidth, lineNumber) {
				var textArray = text.split(""); // 分割成字符串数组
				var temp = "";
				var row = [];
				for (let i = 0; i < textArray.length; i++) {
					if (ctx.measureText(temp).width < contentWidth) {
						temp += textArray[i];
					} else {
						i--; // 这里添加i--是为了防止字符丢失
						row.push(temp);
						temp = "";
					}
				}
				row.push(temp);

				// 如果数组长度大于2，则截取前两个
				if (row.length > lineNumber) {
					let newrow = []
					for (let n = 0; n < lineNumber; n++) {
						newrow.push(row[n]);
					}
					return newrow
				}
				return row
			},
			// 生成海报
			createCanvasImage() {
				uni.showLoading({
					title: '海报生成中...'
				})
				let _this = this;
				let phoneData = uni.getSystemInfoSync()
				this.phoneH = phoneData.windowHeight
				this.phoneW = phoneData.windowWidth
				let scaleW = this.phoneW / 375; //按照苹果留 375*667比例 其他型号手机等比例缩放 显示
				let scaleH = this.phoneH / 667; //按照苹果留 375*667比例 其他型号手机等比例缩放 显示
				const ctx = uni.createCanvasContext('myCanvas',this)
				let pic = this.posterObj.pic //商品主图
				let qrcode = this.posterObj.qrcode

				ctx.draw() //清空原来的画图内容
				ctx.save()
				this.roundRect(ctx, 50, 40, (this.phoneW - 100), (this.phoneH - 120), 10, '#fff', '#fff'); //绘制海报圆角背景白色的
				ctx.restore() //恢复之前保存的绘图上下文 恢复之前保存的绘图上下午即状态 可以继续绘制
				//将网络图片转成本地路径
				uni.getImageInfo({
					src: pic,
					success(res) {
						//覆盖绘制
						//问题：在微信小程序使用canvas绘制圆角图片时，微信调试工具正常显示，android真机都不显示。
						// 原因：因为ctx.clip()剪切区域使用的填充颜色是透明的，所以图片没出来。
						// 解决方案：将剪切区域设置成实体颜色就好了。
						ctx.save();
						_this.roundRect(ctx, (_this.phoneW - ((_this.phoneW - 130))) / 2, 55, (_this.phoneW - 130), 150 * scaleH, 10,
							'#f7f7f7', '#f7f7f7') //绘制图片圆角背景
						ctx.restore()
						ctx.drawImage(res.path, (_this.phoneW - ((_this.phoneW - 130))) / 2, 55, (_this.phoneW - 130), 150 * scaleH, 10)//绘制图
						ctx.draw(true)
					},
					fail() {
						_this.canvasFlag = true
						uni.showToast({
							title: '主图生成失败',
							duration: 2000,
							icon: 'none'
						});
					}
				})
				uni.getImageInfo({
					src: qrcode,
					success(res) {
						ctx.drawImage(res.path,_this.phoneW - 200 * scaleW, 470 * scaleH, 110 * scaleW, 110 * scaleH)
						ctx.draw(true)
					},
					fail() {
						_this.canvasFlag = true
						uni.showToast({
							title: '二维码生成失败',
							duration: 2000,
							icon: 'none'
						});
					}
				})
				// title
				ctx.setGlobalAlpha(1) //不透明
				ctx.setFillStyle('#1c1c1c') //文字颜色：默认黑色
				ctx.setFontSize(14) //设置字体大小，默认10
				ctx.font = 'normal bold 14px sans-serif'
				ctx.fillText(this.posterObj.name, 65, 230 * scaleH)

				ctx.setFontSize(12) //设置字体大小，默认10
				ctx.font = 'normal 12px sans-serif'

				let line = 0
				ctx.fillText(`热度: ${this.posterObj.hits}`, this.phoneW - 120, 230 * scaleH)

				if (this.posterObj.desc) {
					line += 1
					ctx.setFillStyle('#999999')
					ctx.fillText(this.posterObj.desc, 65, (230 + (line * 20)) * scaleH)
				}

				if (this.posterObj.price || this.posterObj.sale) {
					line += 1
				}
				if (this.posterObj.price) {
					ctx.setFillStyle('#c00000')
					ctx.fillText(`¥${this.posterObj.price}`, 65, (230 + (line * 20)) * scaleH)
				}
				if (this.posterObj.sale) {
					ctx.setFillStyle('#999999')
					ctx.fillText(`销量: ${this.posterObj.sale}`, this.phoneW - 120, (230 + (line * 20)) * scaleH)
				}

				//表单
				this.form.forEach(v =>{
					ctx.setFillStyle('#000000')
					ctx.fillText(v.name+`: `, 65, (250 + (line * 20)) * scaleH)
					if(v.type == 'input' || v.type == 'textarea'){
						if(this.posterObj.form[v.field]){
							ctx.setFillStyle('#666666')
							let row = this.canvasMultiLineText(ctx, this.posterObj.form[v.field], this.phoneW-200, (8 - line))
							for (let b = 0; b < row.length; b++) {
								ctx.fillText(row[b], 130, ((250 + (line * 20)) + 15 * b) * scaleH);
							}
							line += row.length-1
						}
						line += 1
					}else if(v.type == 'radio' || v.type == 'checkbox' || v.type == 'select'){
						if(this.posterObj.form[v.field]){
							ctx.setFillStyle('#666666')
							ctx.fillText(this.$getArrayName(v.datas,this.posterObj.form[v.field]), 130, (250 + (line * 20)) * scaleH)
						}
						line += 1
					}else if(v.type == 'tree'){
						if(this.jsonData[v.field]){
							ctx.setFillStyle('#666666')
							let row = this.canvasMultiLineText(ctx, this.jsonData[v.field], this.phoneW-200, (8 - line)) //计算绘制的3行文本
							for (let b = 0; b < row.length; b++) { //一行一行绘制文本
								ctx.fillText(row[b], 130, ((250 + (line * 20)) + 15 * b) * scaleH);
							}
							line += row.length-1
						}
						line += 1
					}
				})
				if(this.posterObj.detail){
					ctx.setFillStyle('#000000')
					ctx.fillText(`详情介绍: `, 65, (250 + (line * 20)) * scaleH)
					let detail = this.posterObj.detail.replace(/<(style|script|iframe)[^>]*?>[\s\S]+?<\/\1\s*>/gi, '').replace(
						/<[^>]+?>/g, '').replace(/\s+/g, ' ').replace(/ /g, ' ').replace(/>/g, ' ').replace(/&(lt|gt|nbsp|amp|quot);/ig, '');
					ctx.setFontSize(10) //设置字体大小，默认10
					ctx.font = 'normal 10px sans-serif'
					ctx.setFillStyle('#666666')
					let row = this.canvasMultiLineText(ctx, detail, this.phoneW-140, (8 - line)) //计算绘制的3行文本
					for (let b = 0; b < row.length; b++) { //一行一行绘制文本
						ctx.fillText(row[b], 70, ((250 + (line * 20)) + 15 * b + 15) * scaleH);
					}
				}
				// 长按/扫描识别查看商品
				ctx.setFontSize(14)
				ctx.setFillStyle('#ff5f33') //文字颜色：默认黑色
				ctx.font = 'normal 14px sans-serif';
				ctx.fillText('长按/扫描', 100, 510 * scaleH)
				ctx.fillText('识别二维码', 95, 530 * scaleH)
				ctx.fillText('了解更多详情', 90, 550 * scaleH)
				// 长按/扫描识别查看商品end
				ctx.draw(true)
				uni.hideLoading();
			},
			// 保存到系统相册
			saveCanvasImage() {
				uni.showLoading({
					title: '保存中...'
				})
				let _this = this;
				// 1-把画布转化成临时文件
				uni.canvasToTempFilePath({
					x: 50,
					y: 40,
					width: (this.phoneW - 100), // 画布的宽
					height: (this.phoneH - 120), // 画布的高
					destWidth: (this.phoneW - 100) * 5,
					destHeight: (this.phoneH - 120) * 5,
					canvasId: 'myCanvas',
					success(res) {
						// 2-保存图片至相册
						uni.saveImageToPhotosAlbum({
							filePath: res.tempFilePath,
							success(res2) {
								uni.hideLoading();
								uni.showToast({
									title: '成功保存至手机相册~',
									duration: 2000,
									icon: 'none'
								})
								_this.canvasCancelEvn();
							},
							fail() {
								uni.showToast({
									title: '保存失败，稍后再试',
									duration: 2000,
									icon: 'none'
								})
								uni.hideLoading();
							}
						})
					},
					fail(res) {
						uni.showToast({
							title: '保存失败，稍后再试',
							duration: 2000,
							icon: 'none'
						})
						uni.hideLoading();
					}
				},this)
			},
			// 取消海报
			canvasCancelEvn() {
				this.$emit('cancel', true)
			}
		}
	}
</script>

<style lang="scss">
	.canvas_box {
		background-color: rgba(0,0,0,.7);
		position: fixed;
		width: 100%;
		height: 100%;
		top:0;
		z-index: 200;
		.canvas {
			position: fixed !important;
			top: 0 !important;
			left: 0 !important;
			display: block !important;
			width: 100% !important;
			height: 100% !important;
			z-index: 201;
		}
		.button-wrapper {
			width: 320rpx;
			position: absolute;
			position: relative;
			text-align: center;
			bottom: 20rpx;
			left: 215rpx;
			z-index: 202;
			.save_btn {
				position: fixed;
				left: 20%;
				bottom: 30rpx;
				font-size: 30rpx;
				width: 200rpx;
				color: #fff;
				border-radius: 36rpx;
				background: #ff3600;
			}
			.close_btn {
				position: fixed;
				bottom: 30rpx;
				width: 150rpx;
				right: 20%;
				color: #fff;
				border-radius: 36rpx;
				background: #aaaaaa;
				font-size: 30rpx;
			}
		}

		
	}
</style>
